/*
 * OPIAM Suite
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package opiam.admin.faare.admin;

import org.apache.xerces.dom.DOMImplementationImpl;

import org.apache.xml.serialize.LineSeparator;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;

import java.io.FileWriter;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;


/**
 * Class which generates some XML data.
 */
public final class XMLWriter
{
    /** Utility class. */
    private XMLWriter()
    {
    }

    /**
     * Generates a part of faare_mapping.xml corresponding to one JavaBean.
     * @param objets List of hashtables containing objects properties.
     */
    public static void genereFaareMappingObj(List objets)
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            DOMImplementation di = new DOMImplementationImpl();
            DocumentType dtd = di.createDocumentType("mapping",
                    "-//OPIAM ADMIN//DTD FAARE MAPPING Configuration 1.0//EN",
                    "http://www.opiam.org/admin/dtd/faare_mapping.dtd");

            Document document = builder.newDocument();

            Element mapping = document.createElement("mapping");
            mapping.appendChild(document.createTextNode("\n\n"));

            Iterator iobjets = objets.iterator();

            while (iobjets.hasNext())
            {
                Hashtable cur = (Hashtable) iobjets.next();

                if (((String) cur.get("class")).equals("") ||
                        ((String) cur.get("mapto")).equals(""))
                {
                    continue;
                }

                Element class1 = document.createElement("class");
                class1.setAttribute("name", (String) cur.get("class"));
                class1.setAttribute("identity", "dn");

                Element mapto1 = document.createElement("map-to");
                mapto1.setAttribute("ldap-oc", (String) cur.get("mapto"));
                class1.appendChild(document.createTextNode("\n"));
                class1.appendChild(mapto1);
                class1.appendChild(document.createTextNode("\n"));

                Element field1 = document.createElement("field");
                field1.setAttribute("name", "dn");
                field1.setAttribute("type", "string");

                Element ldap1 = document.createElement("ldap");
                ldap1.setAttribute("name", "dn");
                field1.appendChild(document.createTextNode("\n"));
                field1.appendChild(ldap1);
                field1.appendChild(document.createTextNode("\n"));
                class1.appendChild(field1);
                class1.appendChild(document.createTextNode("\n"));

                Element field2 = document.createElement("field");
                field2.setAttribute("name", "objectClass");
                field2.setAttribute("type", "string");
                field2.setAttribute("collection", "collection");

                Element ldap2 = document.createElement("ldap");
                ldap2.setAttribute("name", "objectclass");
                field2.appendChild(document.createTextNode("\n"));
                field2.appendChild(ldap2);
                field2.appendChild(document.createTextNode("\n"));
                class1.appendChild(field2);
                class1.appendChild(document.createTextNode("\n"));

                Iterator iattribs = ((List) cur.get("attribs")).iterator();

                while (iattribs.hasNext())
                {
                    Hashtable acur = (Hashtable) iattribs.next();

                    if (((String) acur.get("nom")).equals("") ||
                            ((String) acur.get("type")).equals(""))
                    {
                        continue;
                    }

                    Element fieldi = document.createElement("field");
                    fieldi.setAttribute("name", (String) acur.get("nom"));
                    fieldi.setAttribute("type", (String) acur.get("type"));

                    if (acur.get("collection") != null)
                    {
                        fieldi.setAttribute("collection",
                            (String) acur.get("collection"));
                    }

                    if (acur.get("lazy") != null)
                    {
                        fieldi.setAttribute("lazy", (String) acur.get("lazy"));
                    }

                    Element ldapi = document.createElement("ldap");
                    ldapi.setAttribute("name", (String) acur.get("nom"));
                    fieldi.appendChild(document.createTextNode("\n"));
                    fieldi.appendChild(ldapi);
                    fieldi.appendChild(document.createTextNode("\n"));
                    class1.appendChild(fieldi);
                    class1.appendChild(document.createTextNode("\n"));
                }

                mapping.appendChild(class1);
                mapping.appendChild(document.createTextNode("\n\n"));
            }

            document.appendChild(dtd);
            document.appendChild(document.createComment(
                    "Genere par OPIAM-Admin"));
            document.appendChild(mapping);

            OutputFormat format = new OutputFormat(document, "ISO-8859-1", true);
            format.setLineSeparator(LineSeparator.Unix);
            format.setIndenting(true);
            format.setLineWidth(0);
            format.setPreserveSpace(true);

            XMLSerializer serializer = new XMLSerializer(new FileWriter(
                        "output/partof_faare_mapping.xml"), format);
            serializer.asDOMSerializer();
            serializer.serialize(document);
            serializer.endDocument();
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
}
